#include <iostream>
#include <typeinfo>
#include <assert.h>

using std::cout;
using std::endl;
class Any
{

private:
    class holder
    {
    public:
        virtual ~holder() {}
        virtual const std::type_info& type() = 0;
        virtual holder* clone() = 0;
    };

    template<class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T&val):_val(val) {}
        virtual ~placeholder() {}
        //获取子类对象保存的数据类型
        virtual const std::type_info& type() {return typeid(T);}
        //针对当前的对象自身，克隆出一个新的子类对象
        virtual holder* clone() {return new placeholder(_val);}
    public:
        T _val;
    };
    holder* _content;
public:
    Any():_content(nullptr) {}
    template<class T>
    Any(const T &val):_content(new placeholder<T>(val)) {}
    Any(const Any& other):_content(other._content ? other._content->clone() : nullptr){}
    ~Any(){ delete _content;}

    Any& Swap(Any &other)
    {
        std::swap(_content,other._content);
        return *this;
    }

    template<class T>
    T* get()//返回子类对象保存的数据的指针
    {
        //想要获取的数据类型，必须和保存的数据类型一致
        assert(typeid(T) == _content->type());
        return &((placeholder<T>*)_content)->_val;
    }
    template<class T>
    Any& operator=(const T& val)//赋值运算符的重载函数
    {
        Any(val).Swap(*this);
        return *this;
    }
    Any& operator=(const Any& other)
    {
        Any(other).Swap(*this);
        return *this;
    }
};

class Test{
public:
    Test()
    {
        cout << "构造" << endl;
    }    
    ~Test()
    {
        cout << "析构" << endl;
    }
};
int main()
{
    Any a;
    {
        Test t;
        a = t;
    }
    a = 10;
    int *pa = a.get<int>();
    cout << *pa << endl;
    a = std::string("nihao");
    std::string *ps = a.get<std::string>();
    cout << *ps << endl;
    return 0;
}